﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Evolution.Structure.Globe;
using Evolution.Structure.Globe.Fields;
using EvolutionBaseType;

namespace GameProject
{
    class WorldGenerator
    {
        private static World world;

        public static World generateWorld(int size, double wl, double forest, double mountain, double grass)
        {
            world = new World(size);
            GlobalVar.World = world;

            int sum = (int)(forest + mountain + grass);
            // how much land
            int terrain_count = (int)((1 - (wl / 100)) * (size * size));
            // how much water
            int water_count = (int)(((wl / 100)) * (size * size));

            // calculate percentages / fields for rest

            int forest_count = (int)((forest / sum) * terrain_count);
            int mountain_count = (int)((mountain / sum) * terrain_count);
            int grass_count = (int)((grass / sum) * terrain_count);

            Point p ;

            // GOD SAID : "Everything shall be Land"
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    FieldType fieldType = FieldType.Grassland;
                    p = new Point(i, j);
                    Field field = new Field(fieldType, p);
                    world.setField(p, field);
                }
            }

            p = new Point();
            
            // Put some water on the map
            Random r = new Random();
            
            while (water_count >=0)
            {
                
                p.X = Math.Abs(((int)r.Next(size-1))% size)+1;
                p.Y = Math.Abs(((int)r.Next(size-1))% size)+1;
                FieldType type = FieldType.Water;
                water_count = water_count - cross_fields(p, type);
            }

            // A bissl a Hoiz zum heizen

            while (forest_count >= 0)
            {

                p.X = Math.Abs(((int)r.Next(size - 1)) % size) + 1;
                p.Y = Math.Abs(((int)r.Next(size - 1)) % size) + 1;
                FieldType type = FieldType.Forest;
                forest_count = forest_count - cross_fields(p, type);
            }

            // und wos zum Kraxeln!

            while (mountain_count >= 0)
            {

                p.X = Math.Abs(((int)r.Next(size - 1)) % size) + 1;
                p.Y = Math.Abs(((int)r.Next(size - 1)) % size) + 1;
                FieldType type = FieldType.Mountain;
                mountain_count = mountain_count - cross_fields(p, type);
            }

            return world;
        }

        private static int cross_fields(Point p, FieldType type)
        {
            Point tmp = new Point();
            Field tmp_field;
            int count = 0;
            // rechtes Feld
            if((world.Size-1) > (p.X+1))
            {
                tmp.X = p.X+1;
                tmp.Y = p.Y;
                tmp_field = world.GetFieldByPosition(tmp);
                tmp_field.Type = type;
                count++;
            }
            // linkes Feld
            if ((world.Size - 1) > (p.X - 1))
            {
                tmp.X = p.X-1;
                tmp.Y = p.Y;
                tmp_field = world.GetFieldByPosition(tmp);
                tmp_field.Type = type;
                count++;
            }
            // oberes Feld
            if ((world.Size - 1) > (p.Y - 1))
            {
                tmp.X = p.X;
                tmp.Y = p.Y-1;
                tmp_field = world.GetFieldByPosition(tmp);
                tmp_field.Type = type;
                count++;
            }
            // unteres Feld
            if ((world.Size - 1) > (p.Y + 1))
            {
                tmp.X = p.X;
                tmp.Y = p.Y+1;
                tmp_field = world.GetFieldByPosition(tmp);
                tmp_field.Type = type;
                count++;
            }

            // anvisiertes Feld
            tmp.X = p.X;
            tmp.Y = p.Y;
            tmp_field = world.GetFieldByPosition(tmp);
            tmp_field.Type = type;
            count++;

            return count;

        }
    }
}
